package com.stu.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.stu.dto.ProductSearchDTO;
import com.stu.pojo.Evaluation;
import com.stu.pojo.Pro;
import com.stu.service.EsProService;
import com.stu.service.IEvaluationService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

@RestController
@RequestMapping("/pro")
public class EsProController {
    @Autowired
    private EsProService esProService;
    @Autowired
    private IEvaluationService evaluationService;

    // 1. 提取公共搜索逻辑到单独方法
    private List<Pro> searchProducts(ProductSearchDTO pd) {
        // 使用Stream优化多个条件的查询
        List<Pro> result = Stream.of(
                        Optional.ofNullable(pd.getKeyword())
                                .filter(StringUtils::isNotBlank)
                                .map(esProService::findByProductNameContaining)
                                .orElse(Collections.emptyList()),
                        Optional.ofNullable(pd.getBrand())
                                .filter(StringUtils::isNotBlank)
                                .map(esProService::findByProductBrandContaining)
                                .orElse(Collections.emptyList()),
                        Optional.ofNullable(pd.getType())
                                .filter(StringUtils::isNotBlank)
                                .map(esProService::findByProductTypeContaining)
                                .orElse(Collections.emptyList())
                )
                .flatMap(List::stream)
                .filter(p -> pd.getMinPrice() <= p.getProductPrice() && p.getProductPrice() <= pd.getMaxPrice())
                .distinct()
                .collect(Collectors.toList());

        // 如果没有搜索条件，返回全部
        if (result.isEmpty() &&
                StringUtils.isAllBlank(pd.getKeyword(), pd.getBrand(), pd.getType())) {
            return StreamSupport.stream(esProService.findAll().spliterator(), false)
                    .collect(Collectors.toList());
        }
        return result;
    }

    // 2. 统一分页逻辑
    private List<Pro> paginate(List<Pro> list, int pageNum, int pageSize) {
        int total = list.size();
        int fromIndex = Math.min((pageNum - 1) * pageSize, total);
        int toIndex = Math.min(fromIndex + pageSize, total);
        return list.subList(fromIndex, toIndex);
    }

    // 3. 统一设置评价数量
    private void setEvaluationCounts(List<Pro> products) {
        products.forEach(pro -> {
            long count = evaluationService.count(new QueryWrapper<Evaluation>()
                    .eq("product_id", pro.getId()));
            pro.setXx(String.valueOf(count));
        });
    }

    @GetMapping("/{id}")
    public Optional<Pro> getProById(@PathVariable Integer id) {
        return esProService.findById(id);
    }

    @GetMapping("/allPro")
    public Iterable<Pro> getAllPro() {
        return esProService.findAll();
    }

    @PostMapping("/search")
    public Map<String, Object> searchPro(@RequestBody ProductSearchDTO pd) {
        List<Pro> resultList = searchProducts(pd);
        List<Pro> pageList = paginate(resultList, pd.getPageNum(), pd.getPageSize());
        setEvaluationCounts(pageList);

        return Map.of(
                "data", pageList,
                "total", resultList.size(),
                "pageNum", pd.getPageNum(),
                "pageSize", pd.getPageSize()
        );
    }

    @PostMapping("/numPro/{size}")
    public Map<String, Object> searchRandomPro(@RequestBody ProductSearchDTO pd,
                                               @PathVariable("size") Integer size) {
        if (pd == null) {
            pd = new ProductSearchDTO();
            pd.setMinPrice(0.0);
            pd.setMaxPrice(9999999.9);
            pd.setPageNum(1);
            pd.setPageSize(size);
        }

        List<Pro> resultList = searchProducts(pd);
        Collections.shuffle(resultList);
        List<Pro> randomList = resultList.stream()
                .limit(size)
                .collect(Collectors.toList());
        setEvaluationCounts(randomList);

        return Map.of(
                "data", randomList,
                "total", resultList.size()
        );
    }
}